home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / ax25.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  11.0 KB  |  449 lines

  1. /* Low level AX.25 frame processing - address header */
  2.  
  3. #include <stdio.h>
  4. #include "global.h"
  5. #include "config.h"
  6. #include "mbuf.h"
  7. #include "iface.h"
  8. #include "timer.h"
  9. #include "arp.h"
  10. #include "slip.h"
  11. #include "ax25.h"
  12. #include "lapb.h"
  13. #include "netrom.h"
  14. #include "ip.h"
  15. #include <ctype.h>
  16.  
  17. static int axsend __ARGS((struct iface *iface,char *dest,char *source,
  18.     int cmdrsp,int ctl,struct mbuf *data));
  19.  
  20. /* AX.25 broadcast address: "QST-0" in shifted ascii */
  21. char Ax25_bdcst[AXALEN] = {
  22.     'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1,
  23. };
  24. char Mycall[AXALEN];
  25. struct ax_route *Ax_routes[NHASH];    /* Routing table header */
  26. int Digipeat = 1;    /* Controls digipeating */
  27.  
  28. /* Send IP datagrams across an AX.25 link */
  29. int ax_send(bp,iface,gateway,prec,del,tput,rel)
  30. struct mbuf *bp;
  31. struct iface *iface;
  32. int32 gateway;
  33. int prec;
  34. int del;
  35. int tput;
  36. int rel;
  37. {
  38.     char *hw_addr;
  39.     struct ax25_cb *axp;
  40.     struct mbuf *tbp;
  41.  
  42.     struct ax_route *axr;
  43.     char mode = AX_DEFMODE;        /* default to interface mode */
  44.  
  45.     if(gateway == iface->broadcast) /* This is a broadcast IP datagram */
  46.          return (*iface->output)(iface,Ax25_bdcst,iface->hwaddr,PID_IP,bp);
  47.  
  48.     if((hw_addr = res_arp(iface,ARP_AX25,gateway,bp)) == NULLCHAR)
  49.         return 0;    /* Wait for address resolution */
  50.  
  51.     /* If there's a defined route, get it */
  52.     axr = ax_lookup(hw_addr);
  53.  
  54.     if(axr == NULLAXR) {
  55.         if(iface->flags == DATAGRAM_MODE){
  56.             mode = AX_DATMODE;
  57.         } else {
  58.             mode = AX_VC_MODE;
  59.         }
  60.     } else {
  61.         mode = axr->mode;
  62.         if(mode == AX_DEFMODE) {
  63.             if(iface->flags == DATAGRAM_MODE){
  64.                 mode = AX_DATMODE;
  65.             } else {
  66.                 mode = AX_VC_MODE;
  67.             }
  68.         }    
  69.     }
  70.  
  71.     /* UI frames are used for any one of the following three conditions:
  72.      * 1. The "low delay" bit is set in the type-of-service field.
  73.      * 2. The "reliability" TOS bit is NOT set and the interface is in
  74.      *    datagram mode.
  75.      * 3. The destination is the broadcast address (this is helpful
  76.      *    when broadcasting on an interface that's in connected mode).
  77.      */
  78.     if(del || (!rel && (mode == AX_DATMODE)) || addreq(hw_addr,Ax25_bdcst)){
  79.         /* Use UI frame */
  80.         return (*iface->output)(iface,hw_addr,iface->hwaddr,PID_IP,bp);
  81.     }
  82.     /* Reliability is needed; use I-frames in AX.25 connection */
  83.     if((axp = find_ax25(hw_addr)) == NULLAX25){
  84.         /* Open a new connection */
  85.         axp = open_ax25(iface,iface->hwaddr,hw_addr,
  86.          AX_ACTIVE,Axwindow,s_arcall,s_atcall,s_ascall,-1);
  87.         if(axp == NULLAX25){
  88.             free_p(bp);
  89.             return -1;
  90.         }
  91.     }
  92.     if(axp->state == LAPB_DISCONNECTED){
  93.         est_link(axp);
  94.         lapbstate(axp,LAPB_SETUP);
  95.     }
  96.     /* Insert the PID */
  97.     if((tbp = pushdown(bp,1)) == NULLBUF){
  98.         free_p(bp);
  99.         return -1;
  100.     }
  101.     bp = tbp;
  102.     bp->data[0] = PID_IP;
  103.     if((tbp = segmenter(bp,axp->paclen)) == NULLBUF){
  104.         free_p(bp);
  105.         return -1;
  106.     }
  107.     return send_ax25(axp,tbp,-1);
  108. }
  109. /* Add header and send connectionless (UI) AX.25 packet.
  110.  * Note that the calling order here must match enet_output
  111.  * since ARP also uses it.
  112.  */
  113. int ax_output(iface,dest,source,pid,data)
  114. struct iface *iface;    /* Interface to use; overrides routing table */
  115. char *dest;        /* Destination AX.25 address (7 bytes, shifted) */
  116. char *source;        /* Source AX.25 address (7 bytes, shifted) */
  117. int16 pid;        /* Protocol ID */
  118. struct mbuf *data;    /* Data field (follows PID) */
  119. {
  120.     struct mbuf *bp;
  121.  
  122.     /* Prepend pid to data */
  123.     bp = pushdown(data,1);
  124.     if(bp == NULLBUF){
  125.         free_p(data);
  126.         return -1;
  127.     }
  128.     bp->data[0] = (char)pid;
  129.     return axsend(iface,dest,source,LAPB_COMMAND,UI,bp);
  130. }
  131.  
  132. /* Common subroutine for sendframe() and ax_output() */
  133. static int axsend(iface,dest,source,cmdrsp,ctl,data)
  134. struct iface *iface;    /* Interface to use; overrides routing table */
  135. char *dest;        /* Destination AX.25 address (7 bytes, shifted) */
  136. char *source;        /* Source AX.25 address (7 bytes, shifted) */
  137. int cmdrsp;        /* Command/response indication */
  138. int ctl;        /* Control field */
  139. struct mbuf *data;    /* Data field (includes PID) */
  140. {
  141.     struct mbuf *cbp;
  142.     struct ax25 addr;
  143.     struct ax_route *axr;
  144.     char *idest;
  145.     int rval;
  146.  
  147.     /* If the source addr is unspecified, use the interface address */
  148.     if(source[0] == '\0')
  149.         source = iface->hwaddr;
  150.  
  151.     /* If there's a digipeater route, get it */
  152.     axr = ax_lookup(dest);
  153.  
  154.     memcpy(addr.dest,dest,AXALEN);
  155.     memcpy(addr.source,source,AXALEN);
  156.     addr.cmdrsp = cmdrsp;
  157.  
  158.     if(axr != NULLAXR){
  159.         memcpy(addr.digis,axr->digis,axr->ndigis*AXALEN);
  160.         addr.ndigis = axr->ndigis;
  161.         idest = addr.digis[0];
  162.     } else {
  163.         addr.ndigis = 0;
  164.         idest = dest;
  165.     }
  166.  
  167.     addr.nextdigi = 0;
  168.  
  169.     /* Allocate mbuf for control field, and fill in */
  170.     if((cbp = pushdown(data,1)) == NULLBUF){
  171.         free_p(data);
  172.         return -1;
  173.     }
  174.     cbp->data[0] = ctl;
  175.  
  176.     if((data = htonax25(&addr,cbp)) == NULLBUF){
  177.         free_p(cbp);    /* Also frees data */
  178.         return -1;
  179.     }
  180.     /* This shouldn't be necessary because redirection has already been
  181.      * done at the IP router layer, but just to be safe...
  182.      */
  183.     if(iface->forw != NULLIF){
  184.         logsrc(iface->forw,iface->forw->hwaddr);
  185.         logdest(iface->forw,idest);
  186.         rval = (*iface->forw->raw)(iface->forw,data);
  187.     } else {
  188.         logsrc(iface,iface->hwaddr);
  189.         logdest(iface,idest);
  190.         rval = (*iface->raw)(iface,data);
  191.     }
  192.     return rval;
  193. }
  194.  
  195. extern struct iph *Iph;
  196.  
  197. /* Process incoming AX.25 packets.
  198.  * After optional tracing, the address field is examined. If it is
  199.  * directed to us as a digipeater, repeat it.  If it is addressed to
  200.  * us or to QST-0, kick it upstairs depending on the protocol ID.
  201.  */
  202. void ax_recv(iface,bp)
  203. struct iface *iface;
  204. struct mbuf *bp;
  205. {
  206.     struct mbuf *hbp;
  207.     struct mbuf *nbp;
  208.     char control;
  209.     struct ax25 hdr;
  210.     struct ax25_cb *axp;
  211.     struct ax_route *axr;
  212.     char *isrc,*idest;    /* "immediate" source and destination */
  213.     int pid, len;
  214.     struct ip ip;
  215.  
  216.     /* Pull header off packet and convert to host structure */
  217.     if(ntohax25(&hdr,&bp) < 0){
  218.         /* Something wrong with the header */
  219.         free_p(bp);
  220.         return;
  221.     }
  222.  
  223.     /* If there were digis in this packet, then the last digi was the
  224.      * actual transmitter. Otherwise the source is the transmitter.
  225.      */
  226.     if(hdr.ndigis != 0 && hdr.nextdigi != 0)
  227.         isrc = hdr.digis[hdr.nextdigi-1];
  228.     else
  229.         isrc = hdr.source;
  230.  
  231.     /* Log IP address and AX25 link-address */
  232.     len = len_p(bp);
  233.     if(dup_p(&nbp, bp, 0, len) == len) {
  234.         (void) PULLCHAR(&nbp);
  235.         if(PULLCHAR(&nbp) == PID_IP) {
  236.             ntohip(&ip, &nbp);
  237.             if(ip.version == IPVERSION)
  238.                 log_ipheard(ip.source, iface, isrc);
  239.         }
  240.         free_p(nbp);
  241.     }
  242.  
  243.     if(hdr.nextdigi < hdr.ndigis){
  244.         /* Packet hasn't passed all digipeaters yet. See if
  245.          * we have to repeat it.
  246.          */
  247.         if(Digipeat && addreq(hdr.digis[hdr.nextdigi],iface->hwaddr)){
  248.             /* Yes, kick it back out. htonax25 will set the
  249.              * repeated bit.
  250.              */
  251.             hdr.nextdigi++;
  252.             if((hbp = htonax25(&hdr,bp)) != NULLBUF){
  253.                 if(iface->forw != NULLIF){
  254.                     (*iface->forw->raw)(iface->forw,hbp);
  255.                 } else {
  256.                     (*iface->raw)(iface,hbp);
  257.                 }
  258.                 bp = NULLBUF;
  259.             }
  260.         }
  261.         free_p(bp);    /* Dispose if not forwarded */
  262.         return;
  263.     } else
  264.         idest = hdr.dest;
  265.  
  266.     /* Don't log our own packets if we overhear them, as they're
  267.      * already logged by axsend() and by the digipeater code.
  268.      */
  269.     if(!addreq(isrc,iface->hwaddr)){
  270.         logsrc(iface,isrc);
  271.         logdest(iface,idest);
  272.     }
  273.  
  274.     /* If we reach this point, then the packet has passed all digis,
  275.      * but it is not necessarily for us.
  276.      */
  277.     if(bp == NULLBUF){
  278.         /* Nothing left */
  279.         return;
  280.     }
  281.     /* Sneak a peek at the control field. This kludge is necessary because
  282.      * AX.25 lacks a proper protocol ID field between the address and LAPB
  283.      * sublayers; a control value of UI indicates that LAPB is to be
  284.      * bypassed.
  285.      */
  286.     control = *bp->data & ~PF;
  287.  
  288.     if(uchar(control) == UI){
  289.         char pid;
  290.  
  291.         (void) pullchar(&bp);
  292.         if(pullup(&bp,&pid,1) != 1)
  293.             return;        /* No PID */
  294.         /* Handle packets. Multi-frame messages are not allowed */
  295.         switch(uchar(pid)){
  296.         case PID_IP:
  297.             if(addreq(hdr.dest,Ax25_bdcst))
  298.                 ip_route(iface,bp,1);    /* Broadcast packet */
  299.             else if(addreq(hdr.dest,iface->hwaddr))
  300.                 ip_route(iface,bp,0);    /* Packet directed at us */
  301.             else free_p(bp);
  302.             break;
  303.         case PID_ARP:
  304.             if(addreq(hdr.dest,iface->hwaddr)
  305.                || addreq(hdr.dest,Ax25_bdcst))
  306.                 arp_input(iface,bp);
  307.             else free_p(bp);
  308.             break;
  309.         case PID_NETROM:
  310.             if(addreq(hdr.dest,Nr_nodebc))
  311.                 nr_nodercv(iface,hdr.source,bp);
  312.             else free_p(bp);
  313.             break;
  314.         case PID_NO_L3:
  315.             if(addreq(hdr.dest,iface->hwaddr))
  316.                 beac_input(iface,hdr.source,bp);
  317.             else free_p(bp);
  318.             break;
  319.         default:
  320.             free_p(bp);
  321.             break;
  322.         }
  323.         return;
  324.     }
  325.     /* Everything from here down is LAPB, so drop anything that's
  326.      * not explicitly for us ...
  327.      */
  328.     if(!addreq(hdr.dest,iface->hwaddr)){
  329.         free_p(bp) ;
  330.         return ;
  331.     }
  332.     /* If there's no locally-set entry in the routing table and
  333.      * this packet has digipeaters, create or update it. Leave
  334.      * local routes alone.
  335.      */
  336.     if(((axr = ax_lookup(hdr.source)) == NULLAXR || axr->type == AX_AUTO)
  337.      && hdr.ndigis > 0){
  338.         char digis[MAXDIGIS][AXALEN];
  339.         int i,j;
  340.  
  341.         /* Construct reverse digipeater path */
  342.         for(i=hdr.ndigis-1,j=0;i >= 0;i--,j++){
  343.             memcpy(digis[j],hdr.digis[i],AXALEN);
  344.             digis[j][ALEN] &= ~(E|REPEATED);
  345.         }
  346.         ax_add(hdr.source,AX_AUTO,digis,hdr.ndigis);
  347.     }
  348.  
  349.     /* Find the source address in hash table */
  350.     if((axp = find_ax25(hdr.source)) == NULLAX25){
  351.         /* Create a new ax25 entry for this guy,
  352.          * insert into hash table keyed on his address,
  353.          * and initialize table entries
  354.          */
  355.         if((axp = cr_ax25(hdr.source)) == NULLAX25){
  356.             free_p(bp);
  357.             return;
  358.         }
  359.         /* Swap source and destination */
  360.         memcpy(axp->remote,hdr.source,AXALEN);
  361.         memcpy(axp->local,hdr.dest,AXALEN);
  362.         axp->iface = iface;
  363.     }
  364.     if(hdr.cmdrsp == LAPB_UNKNOWN)
  365.         axp->proto = V1;    /* Old protocol in use */
  366.  
  367.     lapb_input(axp,hdr.cmdrsp,bp);
  368. }
  369. /* General purpose AX.25 frame output */
  370. int
  371. sendframe(axp,cmdrsp,ctl,data)
  372. struct ax25_cb *axp;
  373. int cmdrsp;
  374. int ctl;
  375. struct mbuf *data;
  376. {
  377.     return axsend(axp->iface,axp->remote,axp->local,cmdrsp,ctl,data);
  378. }
  379. void
  380. axarp()
  381. {
  382.     arp_init(ARP_AX25,AXALEN,PID_IP,PID_ARP,10,Ax25_bdcst,pax25,setcall);
  383. }
  384. /* Find a route for an AX.25 address */
  385. struct ax_route *
  386. ax_lookup(target)
  387. char *target;
  388. {
  389.     register struct ax_route *axr;
  390.  
  391.     for(axr = Ax_routes[ax25hash(target)]; axr != NULLAXR; axr = axr->next){
  392.         if(addreq(axr->target,target))
  393.             break;
  394.     }
  395.     return axr;
  396. }
  397. /* Add an entry to the AX.25 routing table */
  398. struct ax_route *
  399. ax_add(target,type,digis,ndigis)
  400. char *target;
  401. int type;
  402. char digis[][AXALEN];
  403. int ndigis;
  404. {
  405.     int16 hval;
  406.     register struct ax_route *axr;
  407.  
  408.     if(ndigis < 0 || ndigis > MAXDIGIS)
  409.         return NULLAXR;
  410.  
  411.     if((axr = ax_lookup(target)) == NULLAXR){
  412.         axr = (struct ax_route *)callocw(1,sizeof(struct ax_route));
  413.         hval = ax25hash(target);
  414.         axr->prev = NULLAXR;
  415.         axr->next = Ax_routes[hval];
  416.         if(axr->next != NULLAXR)
  417.             axr->next->prev = axr;
  418.         Ax_routes[hval] = axr;
  419.         memcpy(axr->target,target,AXALEN);
  420.         axr->ndigis = ndigis;
  421.     }
  422.     axr->type = type;
  423.     axr->mode = AX_DEFMODE;        /* set mode to default */
  424.     if(axr->ndigis != ndigis)
  425.         axr->ndigis = ndigis;
  426.  
  427.     memcpy(axr->digis,digis[0],ndigis*AXALEN);
  428.     return axr;
  429. }
  430. int
  431. ax_drop(target)
  432. char *target;
  433. {
  434.     register struct ax_route *axr;
  435.  
  436.     if((axr = ax_lookup(target)) == NULLAXR)
  437.         return -1;
  438.  
  439.     if(axr->next != NULLAXR)
  440.         axr->next->prev = axr->prev;
  441.     if(axr->prev != NULLAXR)
  442.         axr->prev->next = axr->next;
  443.     else
  444.         Ax_routes[ax25hash(target)] = axr->next;
  445.     free((char *)axr);
  446.     return 0;
  447. }
  448.  
  449.